package main

import (
	"fmt"
	"github.com/unidoc/unipdf/v3/extractor"
	"github.com/unidoc/unipdf/v3/model"
	"log"
	"math"
	"os"
	"sort"
)

func main() {
	pdfPath := "input.pdf"

	// 打开PDF文件
	f, err := os.Open(pdfPath)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// 创建PDF阅读器
	reader, err := model.NewPdfReader(f)
	if err != nil {
		log.Fatal(err)
	}

	// 获取总页数
	totalPages, err := reader.GetNumPages()
	if err != nil {
		log.Fatal(err)
	}

	// 逐页提取表格数据
	for i := 1; i <= totalPages; i++ {
		fmt.Printf("Processing page %d/%d\n", i, totalPages)

		// 获取页面
		page, err := reader.GetPage(i)
		if err != nil {
			log.Print(err)
			continue
		}

		// 创建提取器
		ex, err := extractor.New(page)
		if err != nil {
			log.Print(err)
			continue
		}

		// 提取页面文本（包含位置信息）
		text, _, _, err := ex.ExtractPageText()
		if err != nil {
			log.Print(err)
			continue
		}

		// 提取表格数据（需要自行实现解析逻辑）
		tableData := extractTable(text)
		printTable(tableData)
	}
}

// 基于文本位置解析表格
func extractTable(text *extractor.PageText) [][]string {
	textMarks := text.Marks()

	// 第一步：整理文本按行分组
	var lines [][]*extractor.TextMark
	currentLine := []*extractor.TextMark{}
	currentY := -1.0

	for _, mark := range textMarks.Elements() {
		if currentY == -1 {
			//currentY = mark.Y
			currentY = mark.BBox.Lly
		}

		// Y坐标变化超过阈值视为新行
		if math.Abs(mark.BBox.Lly-currentY) > 2 {
			if len(currentLine) > 0 {
				lines = append(lines, currentLine)
			}
			currentLine = []*extractor.TextMark{}
			currentY = mark.BBox.Lly
		}

		currentLine = append(currentLine, &mark)
	}
	lines = append(lines, currentLine) // 添加最后一行

	// 第二步：检测列位置
	colPositions := detectColumns(lines)

	// 第三步：组织表格数据
	var table [][]string
	for _, line := range lines {
		var row []string
		for _, mark := range line {
			colIndex := findColumnIndex(mark, colPositions)
			// 扩展行切片
			for len(row) <= colIndex {
				row = append(row, "")
			}
			// 合并同一单元格文本
			if row[colIndex] != "" {
				row[colIndex] += " "
			}
			row[colIndex] += mark.Text
		}
		table = append(table, row)
	}

	return table
}

// 检测列的位置（简单版）
func detectColumns(lines [][]*extractor.TextMark) []float64 {
	positionSet := make(map[float64]bool)

	for _, line := range lines {
		for _, mark := range line {
			// 记录所有X坐标（需实际调整阈值）
			for x := mark.BBox.Llx; x < mark.BBox.Llx+mark.BBox.Width(); x += 0.5 {
				positionSet[math.Round(x)] = true
			}
		}
	}

	positions := make([]float64, 0, len(positionSet))
	for pos := range positionSet {
		positions = append(positions, pos)
	}
	sort.Float64s(positions)
	return positions
}

// 查找文本所属列
func findColumnIndex(mark *extractor.TextMark, positions []float64) int {
	midX := mark.BBox.Llx + mark.BBox.Width()/2
	for i, pos := range positions {
		if midX < pos {
			return i
		}
	}
	return len(positions)
}

// 打印表格（演示用）
func printTable(data [][]string) {
	for r, row := range data {
		fmt.Printf("Row %d:\n", r)
		for c, cell := range row {
			fmt.Printf("  Col %d: %s\n", c, cell)
		}
		fmt.Println("----------")
	}
}
